#include <sys_config.h>
#include <osal/osal.h>
#include <basic_types.h>

#include <api/libc/alloc.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>

#include <hld/hld_dev.h>
#include <hld/dmx/dmx_dev.h>
#include <hld/dmx/dmx.h>

#include <api/libtsi/si_types.h>
//#include <api/libtsi/si_table.h>

#include <api/libttx/lib_ttx.h>
#include <api/libttx/ttx_osd.h>
#include <hld/hld_dev.h>
#include <hld/vbi/vbi.h>
#include <hld/vbi/vbi_dev.h>

#define OSD_TTX_MAX_WIDTH 720
#define OSD_TTX_MAX_HEIGHT 576
#define REAL_OSD_TTX_WIDTH   	  (TTX_CHAR_W*40+16)
#ifdef TTX_SUB_PAGE
#define REAL_OSD_TTX_HEIGHT  	  (TTX_CHAR_H*26)
#else
#define REAL_OSD_TTX_HEIGHT  	  (TTX_CHAR_H*25)
#endif


extern struct ttx_config_par g_ttx_pconfig_par;
extern UINT8 transparent_level;
//extern struct dmx_device *dmx_dev;
extern UINT8 ttx_eng_state;
extern UINT8 transparent_value[TTX_TRANSPARENT_LEVEL];

extern const UINT8 ttx_pallette_16[4*16];
extern const UINT8 ttx_pallette_256[4*256];
extern UINT8 *subpage_p26_nation;
extern UINT8 TTX_VscrBuf_8M[ ( ((TTX_CHAR_W*2)>>TTX_FACTOR) ) * TTX_CHAR_H*2];

extern UINT32* get_char_from_cyrillic_1(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_cyrillic_2(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_cyrillic_3(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_greek(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_arabic(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_hebrew(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_g2(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_g2_greek(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_g2_cyrillic(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_g2_arabic(UINT8 charset, UINT8 character, UINT8 i);
extern UINT32* get_char_from_g3(UINT8 charset, UINT8 character, UINT8 i);

extern void TTX_DrawChar_16(UINT16 x, UINT16 y, UINT8 charset, UINT8 fg_color, UINT8 bg_color,UINT8 double_width,UINT8 double_height, UINT8 character, UINT8 p26_char_set);
extern void TTX_DrawChar_256(UINT16 x, UINT16 y, UINT8 charset, UINT8 fg_color, UINT8 bg_color,UINT8 double_width,UINT8 double_height, UINT8 character, UINT8 p26_char_set);

UINT32 osd_ttx_width = REAL_OSD_TTX_WIDTH ;    //the width of the background of the TTX OSD
UINT32 osd_ttx_height = REAL_OSD_TTX_HEIGHT ;   //the height of the background of the TTX OSD
UINT32 osd_ttx_startcol = ((720 - REAL_OSD_TTX_WIDTH)>>1) ; //the uLeft of the TTX_OSD background according to the screen
UINT32 osd_ttx_startrow =((570 - REAL_OSD_TTX_HEIGHT)>>1) ;  //the uTop of the TTX_OSD background according to the screen
UINT32 osd_ttx_xoffset =((REAL_OSD_TTX_WIDTH - (TTX_CHAR_W*40))>>1) ;	  //the uLeft of the region which show the real data of the ttx according to the TTX_OSD background
#ifdef TTX_SUB_PAGE
UINT32 osd_ttx_yoffset =((REAL_OSD_TTX_HEIGHT - (TTX_CHAR_H*26))>>1) ;	  //the uTop of  the region which show the real data of the ttx according to the TTX_OSD background
#else
UINT32 osd_ttx_yoffset =((REAL_OSD_TTX_HEIGHT - (TTX_CHAR_H*25))>>1)
#endif
void TTxOSD_SetSize(UINT32 width,UINT32 height);
void TTxOSD_SetParameter(UINT32 width,UINT32 height);
extern ID ttx_flash_mutex;

__ATTRIBUTE_REUSE_
void  TTXEng_Attach(struct ttx_config_par *pconfig_par)
{
	UINT8 i;

	transparent_level = 0;
	for(i=0;i<TTX_TRANSPARENT_LEVEL;i++)
		transparent_value[i] = 15-i*TTX_TRANSPARENT_STEP;

	ttx_eng_state = TTXENG_OFF;

    if(NULL == pconfig_par)
    {
        ASSERT(0);
    }
	else
		MEMCPY(&g_ttx_pconfig_par, pconfig_par, sizeof(struct ttx_config_par));


//reserved following macros to save code size
#ifdef	SUPPORT_PACKET_26
	g_ttx_pconfig_par.parse_packet26_enable = TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_g2 = get_char_from_g2;

    if(g_ttx_pconfig_par.ttx_sub_page == TRUE)
    {
        subpage_p26_nation = (UINT8 *)MALLOC(25*40*40*sizeof(UINT8));
        if(subpage_p26_nation==NULL)
            ASSERT(0);
        MEMSET(subpage_p26_nation, 0, (25*40*40)*sizeof(UINT8));//cloud
    }
#else
	g_ttx_pconfig_par.parse_packet26_enable = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_g2 = NULL;
#endif
    
#if (SYS_SDRAM_SIZE == 2)
    g_ttx_pconfig_par.ttx_vscrbuf = (UINT8 *)(((UINT32)(__MM_TTX_TMP_BUF_ADDR) & 0x1fffffff) | 0x80000000);
#else
    g_ttx_pconfig_par.ttx_vscrbuf = TTX_VscrBuf_8M;
#endif
    
#ifdef TTX_CYRILLIC_1_SUPPORT
    g_ttx_pconfig_par.ttx_cyrillic_1_support = TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_1 = get_char_from_cyrillic_1;
#else
    g_ttx_pconfig_par.ttx_cyrillic_1_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_1 = NULL;
#endif

#ifdef TTX_CYRILLIC_2_SUPPORT
    g_ttx_pconfig_par.ttx_cyrillic_2_support = TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_2 = get_char_from_cyrillic_2;
#else
    g_ttx_pconfig_par.ttx_cyrillic_2_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_2 = NULL;
#endif

#ifdef TTX_CYRILLIC_3_SUPPORT
    g_ttx_pconfig_par.ttx_cyrillic_3_support = TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_3 = get_char_from_cyrillic_3;
#else
    g_ttx_pconfig_par.ttx_cyrillic_3_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_3 = NULL;
#endif

#ifdef TTX_GREEK_SUPPORT
    g_ttx_pconfig_par.ttx_greek_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_greek = get_char_from_greek;
#else
    g_ttx_pconfig_par.ttx_greek_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_greek = NULL;
#endif

#ifdef TTX_ARABIC_SUPPORT
    g_ttx_pconfig_par.ttx_arabic_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_arabic = get_char_from_arabic;
#else
    g_ttx_pconfig_par.ttx_arabic_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_arabic = NULL;
#endif

#ifdef TTX_HEBREW_SUPPORT
    g_ttx_pconfig_par.ttx_hebrew_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_hebrew = get_char_from_hebrew;
#else
    g_ttx_pconfig_par.ttx_hebrew_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_hebrew = NULL;
#endif

#if	defined(SUPPORT_PACKET_26) && defined(TTX_CYRILLIC_G2_SUPPORT)
    g_ttx_pconfig_par.ttx_cyrillic_g2_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_g2 = get_char_from_g2_cyrillic;
#else
    g_ttx_pconfig_par.ttx_cyrillic_g2_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_cyrillic_g2 = NULL;
#endif

#if	defined(SUPPORT_PACKET_26) && defined(TTX_GREEK_G2_SUPPORT)
    g_ttx_pconfig_par.ttx_greek_g2_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_greek_g2 = get_char_from_g2_greek;
#else
    g_ttx_pconfig_par.ttx_greek_g2_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_greek_g2 = NULL;
#endif

#if	defined(SUPPORT_PACKET_26) && defined(TTX_ARABIC_G2_SUPPORT)
    g_ttx_pconfig_par.ttx_arabic_g2_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_arabic_g2 = get_char_from_g2_arabic;
#else
    g_ttx_pconfig_par.ttx_arabic_g2_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_arabic_g2 = NULL;
#endif

#if	defined(SUPPORT_PACKET_26) && defined(TTX_G3_SUPPORT)
    g_ttx_pconfig_par.ttx_g3_support= TRUE;
    g_ttx_pconfig_par.get_ttxchar_from_g3 = get_char_from_g3;
#else
    g_ttx_pconfig_par.ttx_g3_support = FALSE;
    g_ttx_pconfig_par.get_ttxchar_from_g3 = NULL;
#endif

#if (TTX_COLOR_NUMBER==16)
    g_ttx_pconfig_par.ttx_color_number = 16;
    g_ttx_pconfig_par.ttx_pallette = (UINT8*)ttx_pallette_16;
    g_ttx_pconfig_par.ttx_drawchar = TTX_DrawChar_16;
#elif (TTX_COLOR_NUMBER==256)
    g_ttx_pconfig_par.ttx_color_number = 256;
    g_ttx_pconfig_par.ttx_pallette = (UINT8*)ttx_pallette_256;
    g_ttx_pconfig_par.ttx_drawchar = TTX_DrawChar_256;
#endif
#if 1
 //libc_printf("%s(),line %d\n",__FUNCTION__,__LINE__);
   if( 0 == ttx_flash_mutex )
   {
       if((ttx_flash_mutex = osal_mutex_create()) == OSAL_INVALID_ID)
       {
           ASSERT(0);
       }
   }
 #endif

}


void TTxOSD_SetParameter(UINT32 width,UINT32 height)
{
    osd_ttx_startcol = (OSD_TTX_MAX_WIDTH- width)>>1;
    osd_ttx_startrow = (OSD_TTX_MAX_HEIGHT - height)>>1;
    osd_ttx_xoffset = (width - (TTX_CHAR_W*40))>>1;
  
    #ifdef TTX_SUB_PAGE
        osd_ttx_yoffset = (height - (TTX_CHAR_H*26))>>1;
    #else
        osd_ttx_yoffset = (height - (TTX_CHAR_H*25))>>1;
    #endif
    
}

void TTxOSD_SetSize(UINT32 width,UINT32 height)
{
    UINT8 bValidWidth;
    UINT8 bValidHeight;
    UINT32 width1;
    UINT32 height1;
    bValidWidth = ((width%2 == 0)?1:0);
    bValidHeight = ((height%2 == 0)?1:0); 
    if(1==bValidWidth)
        width1 = width;
    else
        width1 = width+1;

    if(1==bValidWidth)
        height1 = height;
    else
        height1 = height+1;
        
    if(width1 >= REAL_OSD_TTX_WIDTH && width1 <= OSD_TTX_MAX_WIDTH)
        osd_ttx_width =width1 ;
    else if(width1 < REAL_OSD_TTX_WIDTH)
        osd_ttx_width = REAL_OSD_TTX_WIDTH ;
    else
        osd_ttx_width = OSD_TTX_MAX_WIDTH ;
    
    if(height1 >= REAL_OSD_TTX_HEIGHT && height1 <=OSD_TTX_MAX_HEIGHT)
        osd_ttx_height = height1 ;
    else if(height1 < REAL_OSD_TTX_HEIGHT)
        osd_ttx_height = REAL_OSD_TTX_HEIGHT;
    else
        osd_ttx_height = OSD_TTX_MAX_HEIGHT ;
    TTxOSD_SetParameter(osd_ttx_width,osd_ttx_height);
}

